/* Copyright [c] 2018-2028 www.chungen90.com Allrights Reserved*/
#ifndef CG_SDL_RENDER_H
#define CG_SDL_RENDER_H

#include <SDL2\SDL.h>
#include <windows.h>
#include <mutex>
namespace ChunGen { namespace Client { namespace Player {

	class CGBlockRingBuffer
	{
	public:
		CGBlockRingBuffer()
			:buffer(nullptr)
			,bufferSize(0)
			,writeIndex(0)
			,readIndex(0)
            ,bytesCanRead(0)		
		{
			
		}

		void Init(int buffSize)
		{

			buffer =  new uint8_t [buffSize];
			if(!buffer) return;
			this->bufferSize = buffSize;
		}

		void Write(uint8_t *src, int size)
		{
			if(!src ||size == 0) return ;
			std::lock_guard<std::mutex> lk(lock);
			int bytesCanWrite = size < bufferSize - bytesCanRead ? size : (bufferSize - bytesCanRead);

			if(bytesCanWrite <= bufferSize - writeIndex)
			{
				memcpy(buffer + writeIndex,src,bytesCanWrite);
				writeIndex += bytesCanWrite;
				if(writeIndex == bufferSize)
				{
					writeIndex = 0;
				}
			}
			else
			{
				int room = bufferSize - writeIndex;
				memcpy(buffer + writeIndex, src,room);
				int left = bytesCanWrite - room;
				memcpy(buffer, src + room, left);
				writeIndex = left;
			}
			bytesCanRead += bytesCanWrite;

		}

		int Read(uint8_t *dst, int size)
		{
			if(!dst || size == 0) return 0;
			std::lock_guard<std::mutex> lk(lock);
			int bytesRead = size < bytesCanRead ? size : bytesCanRead;
			if(bytesRead <= bufferSize - readIndex)
			{
				memcpy(dst,buffer + readIndex,bytesRead);
				readIndex += bytesRead;
				if(readIndex == bufferSize) readIndex = 0;
			}
			else
			{
				int bytesHead = bufferSize - readIndex;
				memcpy(dst, buffer + readIndex,bytesHead);
				int bytesTail = bytesRead - bytesHead;
				memcpy(dst + readIndex,buffer, bytesTail);
				readIndex = bytesTail;
			}
			bytesCanRead -= bytesRead;
			return bytesRead;
		}
	private:
		uint8_t *buffer;
		int bufferSize;
		int readIndex;
		int  writeIndex;
		int bytesCanRead;
		std::mutex lock;
	};

	class CGSDLRender 
	{
	public:
		CGSDLRender();
		virtual ~CGSDLRender(void);
		
		int InitVideo(HWND hDisplayWindow, int adapterId = 0);

		int CreateVideoSurface(int width, int height);
		int Display(BYTE** data, int* linesize);
		

		int InitAudio(int samples,int channels);
		int PlaySamples(BYTE* buffer, int size) ;
		void Close();
	private:

		SDL_Window *sdlWindow;
        SDL_Renderer *sdlRender;
        SDL_Texture *sdlTexture;

		int width;
		int height;

		CGBlockRingBuffer  *blockingBuffer;
		//CircularBuffer *blockingBuffer;
	private:
	
	};

	
}}}
#endif

